package com.simpou.tests.persistence.jpa;

import com.simpou.commons.utils.file.FileHelper;
import com.simpou.commons.utils.file.PropertyHelper;
import com.simpou.commons.utils.file.filter.ExtensionFileNameFilter;
import com.simpou.commons.utils.file.filter.FileNameFilters;
import com.simpou.commons.utils.file.filter.SubDirectoryFileNameFilter;
import com.simpou.commons.utils.functional.Iterations;
import com.simpou.commons.utils.reflection.condition.AnnotatedElementCondition;
import com.simpou.tests.commons.exception.TestFailedError;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.persistence.Entity;
import javax.persistence.EntityManagerFactory;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;

import com.simpou.tests.persistence.EntitiesTester;
import com.simpou.tests.persistence.TesterHelper;
import org.eclipse.persistence.config.PersistenceUnitProperties;

public class JpaTesterHelper {

    private static List<Class<?>> ENTITIES;

    public static List<Class<?>> scanEntities(final String puName, final String pkgName) {
        if (ENTITIES != null) {
            return ENTITIES;
        }
        final List<Class<?>> classes = TesterHelper.scanEntities(puName, pkgName);
        final List<Class<?>> filtered = Iterations.filter(classes, new AnnotatedElementCondition<Class<?>>(Entity.class));
        if (filtered.isEmpty()) {
            throw new TestFailedError("No entities found.");
        } else {
            ENTITIES = filtered;
        }
        return ENTITIES;
    }

//    static ClassLoader getClassLoader(String... classLoaderUrls) {
//        final String[] urls = ArraysHelper.concat(DEF_CLASSLOADER_URLS, classLoaderUrls);
//        ClassLoader classLoader;
//        try {
//            classLoader = ClassLoaders.newClassLoaderByUrls(urls);
//        } catch (MalformedURLException ex) {
//            throw new RuntimeException(ex);
//        }
//        return classLoader;
//    }

    public static EntityManagerFactory newEMFactory(final String puName) {
        return newEMFactory(puName, true);
    }

    public static EntityManagerFactory newEMFactory(final String puName, final boolean configDb) {
//        final List<Class<? extends BaseEntity>> scanneds = scanEntities();
        Map props = new HashMap();
        if (configDb) {
            props.put(PersistenceUnitProperties.JDBC_URL, "jdbc:hsqldb:mem:simpou-tests");
            props.put(PersistenceUnitProperties.JDBC_PASSWORD, "sa");
            props.put(PersistenceUnitProperties.JDBC_DRIVER, "org.hsqldb.jdbcDriver");
            props.put(PersistenceUnitProperties.JDBC_USER, "");
            props.put(PersistenceUnitProperties.DDL_GENERATION, PersistenceUnitProperties.DROP_AND_CREATE);
        }
        props.put(PersistenceUnitProperties.LOGGING_LEVEL, "FINE");
        props.put("eclipselink.logging.level.sql", "FINE");
        props.put("eclipselink.logging.level.cache", "FINE");
        props.put(PersistenceUnitProperties.LOGGING_PARAMETERS, "FINE");
        props.put(PersistenceUnitProperties.LOGGING_TIMESTAMP, "true");
        props.put(PersistenceUnitProperties.LOGGING_EXCEPTIONS, "true");

        EntityManagerFactory emf = Persistence.createEntityManagerFactory(puName, props);
        return emf;
    }
}
